<template>
  <el-form
    ref="formRef"
    v-loading="loading"
    :model="formData"
    :rules="rules"
    label-width="112px"
    class="product-form"
  >
    <el-card shadow="never" class="section-card">
      <template #header>基础信息</template>
      <el-row :gutter="16">
        <el-col v-if="!isSellerClient" :md="8" :sm="12" :xs="24">
          <el-form-item label="卖家组织ID" prop="seller_org_id">
            <el-input-number
              v-model="formData.seller_org_id"
              :min="1"
              :controls="false"
              placeholder="请输入卖家组织ID"
              class="w-full"
            />
          </el-form-item>
        </el-col>
        <el-col v-if="!isSellerClient" :md="8" :sm="12" :xs="24">
          <el-form-item label="卖家用户ID" prop="seller_user_id">
            <el-input-number
              v-model="formData.seller_user_id"
              :min="1"
              :controls="false"
              placeholder="可选，卖家用户ID"
              class="w-full"
            />
          </el-form-item>
        </el-col>
        <el-col v-if="showManagementFields" :md="8" :sm="12" :xs="24">
          <el-form-item label="所属区域" prop="region_id">
            <el-tree-select
              v-model="formData.region_id"
              :data="regionOptions"
              :props="regionSelectProps"
              check-strictly
              :render-after-expand="false"
              placeholder="将根据卖家组织自动设置"
              class="w-full"
              disabled
            />
          </el-form-item>
        </el-col>
        <el-col :md="8" :sm="12" :xs="24">
          <el-form-item label="商品标题" prop="title">
            <el-input
              v-model.trim="formData.title"
              placeholder="请输入商品标题"
            />
          </el-form-item>
        </el-col>
        <el-col v-if="showManagementFields" :md="8" :sm="12" :xs="24">
          <el-form-item label="副标题" prop="subtitle">
            <el-input
              v-model.trim="formData.subtitle"
              placeholder="可选，副标题"
            />
          </el-form-item>
        </el-col>
        <el-col :md="8" :sm="12" :xs="24">
          <el-form-item label="商品型号" prop="model">
            <el-input v-model.trim="formData.model" placeholder="请输入型号" />
          </el-form-item>
        </el-col>
        <el-col :md="8" :sm="12" :xs="24">
          <el-form-item label="SKU编码" prop="sku_code">
            <el-input
              v-model.trim="formData.sku_code"
              placeholder="可选，SKU编码"
            />
          </el-form-item>
        </el-col>
        <el-col :md="8" :sm="12" :xs="24">
          <el-form-item label="所属分类" prop="category_id">
            <el-tree-select
              v-model="formData.category_id"
              :data="categoryOptions"
              placeholder="请选择分类"
              filterable
              :render-after-expand="false"
              check-strictly
              class="w-full"
            />
          </el-form-item>
        </el-col>
        <el-col :md="8" :sm="12" :xs="24">
          <el-form-item label="品牌" prop="brand_id">
            <el-select
              v-model="formData.brand_id"
              clearable
              filterable
              placeholder="请选择品牌"
              class="w-full"
            >
              <el-option
                v-for="item in brandOptions"
                :key="item.id"
                :label="item.name"
                :value="item.id"
              />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
    </el-card>

    <el-card shadow="never" class="section-card">
      <template #header>价格与库存</template>
      <el-row :gutter="16">
        <el-col :md="6" :sm="12" :xs="24">
          <el-form-item label="默认价格" prop="default_price">
            <el-input-number
              v-model="formData.default_price"
              :min="0"
              :controls="false"
              :precision="2"
              class="w-full"
              placeholder="请输入价格"
            />
          </el-form-item>
        </el-col>
        <el-col :md="6" :sm="12" :xs="24">
          <el-form-item label="默认库存" prop="default_stock">
            <el-input-number
              v-model="formData.default_stock"
              :min="0"
              :controls="false"
              class="w-full"
              placeholder="请输入库存"
            />
          </el-form-item>
        </el-col>
        <el-col v-if="showManagementFields" :md="6" :sm="12" :xs="24">
          <el-form-item label="最小起订量" prop="min_order_qty">
            <el-input-number
              v-model="formData.min_order_qty"
              :min="1"
              :controls="false"
              class="w-full"
              placeholder="可选"
            />
          </el-form-item>
        </el-col>
        <el-col v-if="showManagementFields" :md="6" :sm="12" :xs="24">
          <el-form-item label="增量" prop="step_qty">
            <el-input-number
              v-model="formData.step_qty"
              :min="1"
              :controls="false"
              class="w-full"
              placeholder="可选"
            />
          </el-form-item>
        </el-col>
        <el-col :md="6" :sm="12" :xs="24">
          <el-form-item label="单位" prop="unit">
            <el-input v-model.trim="formData.unit" placeholder="请输入单位" />
          </el-form-item>
        </el-col>
      </el-row>
    </el-card>

    <el-card v-if="showManagementFields" shadow="never" class="section-card">
      <template #header>物流与规格</template>
      <el-row :gutter="16">
        <el-col :md="6" :sm="12" :xs="24">
          <el-form-item label="重量" prop="weight_value">
            <div class="flex gap-2">
              <el-input-number
                v-model="formData.weight_value"
                :min="0"
                :controls="false"
                class="flex-1"
                placeholder="重量"
              />
              <el-input
                v-model="formData.weight_unit"
                placeholder="单位"
                style="width: 80px"
              />
            </div>
          </el-form-item>
        </el-col>
        <el-col :md="6" :sm="12" :xs="24">
          <el-form-item label="尺寸 (长)" prop="size_length">
            <el-input-number
              v-model="formData.size_length"
              :min="0"
              :controls="false"
              class="w-full"
              placeholder="可选"
            />
          </el-form-item>
        </el-col>
        <el-col :md="6" :sm="12" :xs="24">
          <el-form-item label="尺寸 (宽)" prop="size_width">
            <el-input-number
              v-model="formData.size_width"
              :min="0"
              :controls="false"
              class="w-full"
              placeholder="可选"
            />
          </el-form-item>
        </el-col>
        <el-col :md="6" :sm="12" :xs="24">
          <el-form-item label="尺寸 (高)" prop="size_height">
            <el-input-number
              v-model="formData.size_height"
              :min="0"
              :controls="false"
              class="w-full"
              placeholder="可选"
            />
          </el-form-item>
        </el-col>
        <el-col :md="6" :sm="12" :xs="24">
          <el-form-item label="产地" prop="origin_country">
            <el-input
              v-model.trim="formData.origin_country"
              placeholder="可选，产地"
            />
          </el-form-item>
        </el-col>
        <el-col :md="6" :sm="12" :xs="24">
          <el-form-item label="生产日期" prop="manufactured_at">
            <el-date-picker
              v-model="formData.manufactured_at"
              type="date"
              value-format="YYYY-MM-DD"
              placeholder="可选"
              class="w-full"
            />
          </el-form-item>
        </el-col>
      </el-row>
    </el-card>

    <el-card shadow="never" class="section-card">
      <template #header>媒体信息</template>
      <el-row :gutter="16">
        <el-col :span="24">
          <el-form-item label="商品图片" prop="gallery">
            <el-upload
              class="upload-gallery"
              list-type="picture-card"
              :file-list="imageFileList"
              :http-request="handleImageUpload"
              :limit="10"
              :on-remove="handleImageRemove"
              :on-preview="handleImagePreview"
            >
              <el-icon><Plus /></el-icon>
            </el-upload>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="视频地址">
            <el-input
              v-model.trim="videoInput"
              placeholder="输入视频地址后回车添加"
              @keyup.enter="appendVideo"
            />
            <div v-if="formData.videos.length" class="video-list">
              <el-tag
                v-for="(item, index) in formData.videos"
                :key="item"
                closable
                @close="removeVideo(index)"
              >
                {{ item }}
              </el-tag>
            </div>
          </el-form-item>
        </el-col>
      </el-row>
    </el-card>

    <el-card shadow="never" class="section-card">
      <template #header>内容详情</template>
      <el-row :gutter="16">
        <el-col :span="24">
          <el-form-item label="摘要" prop="summary">
            <el-input
              v-model.trim="formData.summary"
              type="textarea"
              :rows="2"
              placeholder="请输入摘要"
            />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="详细描述" prop="description">
            <WangEditor v-model="formData.description" style="width: 100%" />
          </el-form-item>
        </el-col>
      </el-row>
    </el-card>

    <el-card v-if="showManagementFields" shadow="never" class="section-card">
      <template #header>发布设置</template>
      <el-row :gutter="16">
        <el-col :md="6" :sm="12" :xs="24">
          <el-form-item label="商品状态" prop="status">
            <el-select v-model="formData.status">
              <el-option label="草稿" :value="0" />
              <el-option label="上架" :value="1" />
              <el-option label="下架" :value="2" />
              <el-option label="禁用" :value="3" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :md="6" :sm="12" :xs="24">
          <el-form-item label="审核状态" prop="audit_status">
            <el-select v-model="formData.audit_status">
              <el-option label="待审核" :value="0" />
              <el-option label="已通过" :value="1" />
              <el-option label="已驳回" :value="2" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :md="8" :sm="12" :xs="24">
          <el-form-item label="发布时间" prop="publish_time">
            <el-date-picker
              v-model="formData.publish_time"
              type="datetime"
              value-format="YYYY-MM-DD HH:mm:ss"
              placeholder="可选，发布时间"
              class="w-full"
            />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="备注" prop="remark">
            <el-input
              v-model.trim="formData.remark"
              type="textarea"
              :rows="2"
              placeholder="可选，备注"
            />
          </el-form-item>
        </el-col>
      </el-row>
    </el-card>
    <ElImageViewer
      v-if="imagePreview.visible && imagePreview.url"
      :url-list="[imagePreview.url]"
      @close="imagePreview.visible = false"
    />
  </el-form>
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch, onMounted } from "vue";
import type {
  FormInstance,
  FormRules,
  UploadFile,
  UploadProps,
  UploadRequestHandler
} from "element-plus";
import { ElMessage, ElImageViewer } from "element-plus";
import { Plus } from "@element-plus/icons-vue";
import WangEditor from "@/components/WangEditor.vue";
import productApi, {
  fetchBrandOptions,
  fetchCategoryTree,
  type ProductDetail,
  type ProductSubmitPayload
} from "@/api/system/product/product";
import { fetchRegionTree } from "@/api/system/region/region";
import { uploadFile } from "@/utils/upload";
import { useUserStoreHook } from "@/store/modules/user";

interface BrandOption {
  id: number;
  name: string;
  slug?: string;
}

interface CategoryNode {
  id: number;
  name: string;
  children?: CategoryNode[];
}

interface CategoryOption {
  value: number;
  label: string;
  children?: CategoryOption[];
}

interface RegionNode {
  id: number;
  name?: string;
  label?: string;
  children?: RegionNode[];
}

interface RegionOption {
  id: number;
  label: string;
  value: number;
  children?: RegionOption[];
}

const props = defineProps<{
  id?: number | null;
  brandOptions?: BrandOption[];
  categoryTree?: CategoryNode[];
  regionTree?: RegionNode[];
}>();

const emit = defineEmits<{
  (e: "submitted"): void;
}>();

const formRef = ref<FormInstance>();
const loading = ref(false);
const imagePreview = ref<{ visible: boolean; url: string | null }>({
  visible: false,
  url: null
});

const remoteBrandOptions = ref<BrandOption[]>(props.brandOptions ?? []);
const remoteCategoryTree = ref<CategoryNode[]>(props.categoryTree ?? []);
const remoteRegionTree = ref<RegionNode[]>(props.regionTree ?? []);

const formData = reactive<
  ProductSubmitPayload & {
    seller_user_id: number | null;
    region_id: number | null;
    subtitle: string;
    model: string;
    sku_code: string;
    min_order_qty: number | null;
    step_qty: number | null;
    weight_value: number | null;
    weight_unit: string;
    size_length: number | null;
    size_width: number | null;
    size_height: number | null;
    origin_country: string;
    manufactured_at: string | null;
    summary: string;
    description: string;
    gallery: string[];
    videos: string[];
    attachments: Array<Record<string, any>>;
    remark: string;
  }
>({
  seller_org_id: NaN,
  seller_user_id: null,
  region_id: null,
  category_id: NaN,
  brand_id: null,
  title: "",
  subtitle: "",
  model: "",
  sku_code: "",
  default_price: 0,
  default_stock: 0,
  unit: "",
  min_order_qty: null,
  step_qty: null,
  weight_value: null,
  weight_unit: "",
  size_length: null,
  size_width: null,
  size_height: null,
  origin_country: "",
  manufactured_at: null,
  summary: "",
  description: "",
  attachments: [],
  attributes: [],
  gallery: [],
  videos: [],
  status: 0,
  audit_status: 0,
  publish_time: null,
  remark: ""
});

const imageFileList = ref<UploadFile[]>([]);
const videoInput = ref("");

const userStore = useUserStoreHook();
const resolvedClientType = computed(
  () => (userStore.clientType ?? "admin").toLowerCase()
);
const isSellerClient = computed(() =>
  resolvedClientType.value.startsWith("seller")
);
const showManagementFields = computed(() => !isSellerClient.value);

const rules = computed<FormRules>(() => ({
  seller_org_id: isSellerClient.value
    ? []
    : [
        { required: true, message: "请输入卖家组织ID", trigger: "blur" },
        {
          validator: (_rule, value, callback) => {
            if (!value || Number(value) <= 0) {
              callback(new Error("卖家组织ID必须大于0"));
            } else {
              callback();
            }
          },
          trigger: "blur"
        }
      ],
  category_id: [{ required: true, message: "请选择分类", trigger: "change" }],
  model: [{ required: true, message: "请输入商品型号", trigger: "blur" }],
  default_price: [{ required: true, message: "请输入价格", trigger: "blur" }],
  default_stock: [{ required: true, message: "请输入库存", trigger: "blur" }],
  gallery: [
    {
      validator: (_rule, value, callback) => {
        if (!Array.isArray(value) || value.length === 0) {
          callback(new Error("请至少上传一张商品图片"));
          return;
        }
        callback();
      },
      trigger: "change"
    }
  ]
}));

const categoryOptions = computed<CategoryOption[]>(() => {
  const build = (nodes: CategoryNode[]): CategoryOption[] =>
    nodes.map(node => ({
      value: node.id,
      label: node.name,
      children: node.children ? build(node.children) : undefined
    }));
  return build(remoteCategoryTree.value ?? []);
});

const regionSelectProps = {
  label: "label",
  value: "id",
  children: "children"
} as const;

const regionOptions = computed<RegionOption[]>(() => {
  const build = (nodes: RegionNode[], parentLabel = ""): RegionOption[] =>
    nodes.map(node => {
      const id = Number(node.id);
      const name = node.label ?? node.name ?? `区域 ${id}`;
      const currentLabel = parentLabel ? `${parentLabel} / ${name}` : name;
      const option: RegionOption = {
        id,
        value: id,
        label: currentLabel
      };
      if (Array.isArray(node.children) && node.children.length) {
        option.children = build(node.children, currentLabel);
      }
      return option;
    });

  return build(remoteRegionTree.value ?? []);
});

const syncImageFileList = () => {
  imageFileList.value = formData.gallery.map(url => ({
    name: url.split("/").pop() ?? url,
    url
  }));
};

const handleImageUpload: UploadRequestHandler = option => {
  uploadFile(
    option,
    percent => {
      option.onProgress?.({ percent } as any);
    },
    url => {
      formData.gallery.push(url);
      syncImageFileList();
      option.onSuccess?.({ url } as any);
    },
    error => {
      option.onError?.(new Error(error ?? "上传失败"));
      ElMessage.error(error ?? "上传失败");
    }
  );
};

const handleImageRemove: UploadProps["onRemove"] = file => {
  const url = file?.url;
  if (!url) return;
  formData.gallery = formData.gallery.filter(item => item !== url);
  syncImageFileList();
};

const handleImagePreview: UploadProps["onPreview"] = file => {
  if (!file.url) return;
  imagePreview.value = { visible: true, url: file.url };
};

const appendVideo = () => {
  const url = videoInput.value.trim();
  if (!url) return;
  formData.videos.push(url);
  videoInput.value = "";
};

const removeVideo = (index: number) => {
  formData.videos.splice(index, 1);
};

const mapDetailToForm = (detail: ProductDetail) => {
  formData.seller_org_id = detail.seller_org_id;
  formData.seller_user_id = detail.seller_user_id ?? null;
  formData.region_id =
    detail.region_id !== null && detail.region_id !== undefined
      ? Number(detail.region_id)
      : null;
  formData.title = detail.title ?? "";
  formData.subtitle = detail.subtitle ?? "";
  formData.model = detail.model ?? "";
  formData.sku_code = detail.sku_code ?? "";
  formData.category_id = detail.category_id ?? NaN;
  formData.brand_id = detail.brand_id ?? null;
  formData.default_price = detail.default_price ?? 0;
  formData.default_stock = detail.default_stock ?? 0;
  formData.unit = detail.unit ?? "";
  formData.min_order_qty = detail.min_order_qty ?? null;
  formData.step_qty = detail.step_qty ?? null;
  formData.weight_value = detail.weight_value ?? null;
  formData.weight_unit = detail.weight_unit ?? "";
  formData.size_length = detail.size_length ?? null;
  formData.size_width = detail.size_width ?? null;
  formData.size_height = detail.size_height ?? null;
  formData.origin_country = detail.origin_country ?? "";
  formData.manufactured_at = detail.manufactured_at ?? null;
  formData.summary = detail.summary ?? "";
  formData.description = detail.description ?? "";
  formData.gallery = detail.gallery ?? [];
  formData.videos = detail.videos ?? [];
  formData.attachments = detail.attachments ?? [];
  formData.attributes = detail.attributes ?? [];
  formData.status = detail.status ?? 0;
  formData.audit_status = detail.audit_status ?? 0;
  formData.publish_time = detail.publish_time ?? null;
  formData.remark = detail.remark ?? "";
  syncImageFileList();
};

const fetchDetail = async (id: number) => {
  loading.value = true;
  try {
    const detail = await productApi.fetchDetail(id);
    mapDetailToForm(detail);
  } catch (error: any) {
    ElMessage.error(error?.message ?? "获取商品详情失败");
  } finally {
    loading.value = false;
  }
};

const ensureMeta = async () => {
  if (!remoteBrandOptions.value.length) {
    remoteBrandOptions.value = await fetchBrandOptions();
  }
  if (!remoteCategoryTree.value.length) {
    remoteCategoryTree.value = await fetchCategoryTree();
  }
  if (!remoteRegionTree.value.length) {
    remoteRegionTree.value = await fetchRegionTree();
  }
};

const resetFormState = () => {
  Object.assign(formData, {
    seller_org_id: NaN,
    seller_user_id: null,
    region_id: null,
    title: "",
    subtitle: "",
    model: "",
    sku_code: "",
    category_id: NaN,
    brand_id: null,
    default_price: 0,
    default_stock: 0,
    unit: "",
    min_order_qty: null,
    step_qty: null,
    weight_value: null,
    weight_unit: "",
    size_length: null,
    size_width: null,
    size_height: null,
    origin_country: "",
    manufactured_at: null,
    summary: "",
    description: "",
    gallery: [],
    videos: [],
    attachments: [],
    attributes: [],
    status: 0,
    audit_status: 0,
    publish_time: null,
    remark: ""
  });
  syncImageFileList();
  videoInput.value = "";
};

watch(
  () => props.brandOptions,
  value => {
    if (value && value.length) {
      remoteBrandOptions.value = value;
    }
  },
  { immediate: true }
);

watch(
  () => props.categoryTree,
  value => {
    if (value && value.length) {
      remoteCategoryTree.value = value;
    }
  },
  { immediate: true }
);

watch(
  () => props.regionTree,
  value => {
    if (value && value.length) {
      remoteRegionTree.value = value;
    }
  },
  { immediate: true }
);

onMounted(async () => {
  await ensureMeta();
  if (props.id) {
    await fetchDetail(props.id);
  } else {
    resetFormState();
  }
});

watch(
  () => props.id,
  async newId => {
    resetFormState();
    if (newId) {
      await fetchDetail(newId);
    }
  }
);

const handleSubmit = async () => {
  if (!formRef.value) return false;
  try {
    await formRef.value.validate();
  } catch {
    return false;
  }

  const payload: ProductSubmitPayload = {
    seller_org_id: Number(formData.seller_org_id),
    seller_user_id: formData.seller_user_id ?? undefined,
    region_id: formData.region_id ?? undefined,
    category_id: Number(formData.category_id),
    brand_id:
      formData.brand_id !== null ? Number(formData.brand_id) : undefined,
    title: formData.title,
    subtitle: formData.subtitle,
    model: formData.model,
    sku_code: formData.sku_code,
    default_price: Number(formData.default_price ?? 0),
    default_stock: Number(formData.default_stock ?? 0),
    unit: formData.unit,
    min_order_qty: formData.min_order_qty ?? undefined,
    step_qty: formData.step_qty ?? undefined,
    weight_value: formData.weight_value ?? undefined,
    weight_unit: formData.weight_unit,
    size_length: formData.size_length ?? undefined,
    size_width: formData.size_width ?? undefined,
    size_height: formData.size_height ?? undefined,
    origin_country: formData.origin_country,
    manufactured_at: formData.manufactured_at ?? undefined,
    summary: formData.summary,
    description: formData.description,
    gallery: formData.gallery,
    videos: formData.videos,
    attachments: formData.attachments,
    attributes: formData.attributes,
    status: formData.status,
    audit_status: formData.audit_status,
    publish_time: formData.publish_time ?? undefined,
    remark: formData.remark
  };

  loading.value = true;
  try {
    if (props.id) {
      await productApi.update(props.id, payload);
      ElMessage.success("商品已更新");
    } else {
      await productApi.create(payload);
      ElMessage.success("商品已创建");
    }
    emit("submitted");
    return true;
  } catch (error: any) {
    ElMessage.error(error?.message ?? "保存商品失败");
    return false;
  } finally {
    loading.value = false;
  }
};

defineExpose({
  submitForm: handleSubmit
});
</script>

<style scoped>
.product-form {
  max-height: 80vh;
  overflow-y: auto;
  padding-right: 4px;
}

.section-card + .section-card {
  margin-top: 16px;
}

.upload-gallery {
  width: 100%;
}

.video-list {
  margin-top: 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
</style>
